package cn.edu.tju.elm.controller;

import cn.edu.tju.elm.common.response.HttpResult;
import cn.edu.tju.elm.model.DTO.WalletTransactionDTO;
import cn.edu.tju.elm.model.entity.VirtualWallet;
import cn.edu.tju.elm.model.entity.WalletTransaction;
import cn.edu.tju.elm.service.VirtualWalletService;
import cn.edu.tju.elm.service.WalletMigrationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

@RestController
@RequestMapping("/api/wallet")
@Tag(name = "虚拟钱包", description = "提供钱包的充值、提现、支付、查询等功能，支持资金冻结解冻、透支额度设置等")
@RequiredArgsConstructor
public class VirtualWalletController {

    private final VirtualWalletService virtualWalletService;
    private final WalletMigrationService walletMigrationService; // 添加这个依赖

    @GetMapping("/balance")
    @Operation(
            summary = "查询钱包余额",
            description = "获取当前用户的虚拟钱包余额信息，包括可用余额、冻结余额和透支额度"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "查询成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "404", description = "钱包不存在")
    })
    public HttpResult<VirtualWallet> getBalance() {
        VirtualWallet wallet = virtualWalletService.getCurrentUserWallet();
        return HttpResult.ok(wallet);
    }

    @PostMapping("/recharge")
    @Operation(
            summary = "钱包充值",
            description = "向虚拟钱包充值，充值金额必须大于0，可能会根据奖励规则获得额外奖励"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "充值成功"),
            @ApiResponse(responseCode = "400", description = "充值金额无效（小于等于0）"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "404", description = "钱包不存在")
    })
    public HttpResult<VirtualWallet> recharge(
            @Parameter(description = "充值金额，必须大于0", required = true, example = "100.00")
            @RequestParam BigDecimal amount,
            @Parameter(description = "充值备注", example = "支付宝充值")
            @RequestParam(required = false) String remark) {
        VirtualWallet wallet = virtualWalletService.recharge(amount, remark);
        return HttpResult.ok(wallet);
    }

    @PostMapping("/withdraw")
    @Operation(
            summary = "钱包提现",
            description = "从虚拟钱包提现，提现金额必须大于0且不超过可用余额（含透支额度），可能会扣除手续费"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "提现成功"),
            @ApiResponse(responseCode = "400", description = "提现金额无效或余额不足"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "404", description = "钱包不存在")
    })
    public HttpResult<VirtualWallet> withdraw(
            @Parameter(description = "提现金额，必须大于0", required = true, example = "50.00")
            @RequestParam BigDecimal amount,
            @Parameter(description = "提现备注", example = "提现到银行卡")
            @RequestParam(required = false) String remark) {
        VirtualWallet wallet = virtualWalletService.withdraw(amount, remark);
        return HttpResult.ok(wallet);
    }

    @PostMapping("/pay-order")
    @Operation(
            summary = "钱包支付订单",
            description = "使用虚拟钱包余额支付指定订单，支付成功后商家资金将处于冻结状态，直到确认收货"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "支付成功"),
            @ApiResponse(responseCode = "400", description = "余额不足或订单状态不允许支付"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "只能支付自己的订单"),
            @ApiResponse(responseCode = "404", description = "订单或钱包不存在")
    })
    public HttpResult<VirtualWallet> payOrder(
            @Parameter(description = "订单ID", required = true, example = "1")
            @RequestParam Long orderId) {
        VirtualWallet wallet = virtualWalletService.payOrder(orderId);
        return HttpResult.ok(wallet);
    }

    @PostMapping("/confirm-order")
    @Operation(
            summary = "确认收货",
            description = "确认订单收货，解冻商家的订单资金，使其变为可用余额"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "确认收货成功"),
            @ApiResponse(responseCode = "400", description = "订单状态不允许确认收货"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "只能确认自己的订单"),
            @ApiResponse(responseCode = "404", description = "订单不存在")
    })
    public HttpResult<String> confirmOrder(
            @Parameter(description = "订单ID", required = true, example = "1")
            @RequestParam Long orderId) {
        virtualWalletService.confirmOrder(orderId);
        return HttpResult.ok("确认收货成功");
    }

    @GetMapping("/transactions")
    @Operation(
            summary = "查询交易流水",
            description = "获取当前用户虚拟钱包的所有交易历史记录，包括充值、提现、支付等"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "查询成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "404", description = "钱包不存在")
    })
    public HttpResult<List<WalletTransactionDTO>> getTransactions() {
        List<WalletTransactionDTO> transactionDTOs = virtualWalletService.getTransactionHistory();
        return HttpResult.ok(transactionDTOs);
    }

    @PostMapping("/overdraft-limit")
    @Operation(
            summary = "设置透支额度",
            description = "设置虚拟钱包的透支额度，通常仅限VIP用户使用，设置后可在余额不足时进行透支"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "设置成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "权限不足，需要VIP权限"),
            @ApiResponse(responseCode = "404", description = "钱包不存在")
    })
    public HttpResult<VirtualWallet> setOverdraftLimit(
            @Parameter(description = "透支额度，必须大于等于0", required = true, example = "500.00")
            @RequestParam BigDecimal limit) {
        VirtualWallet wallet = virtualWalletService.setOverdraftLimit(limit);
        return HttpResult.ok(wallet);
    }

    @PostMapping("/upgrade-vip")
    @Operation(
            summary = "升级为VIP用户",
            description = "免费升级为VIP用户，享受1000元透支额度"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "升级成功"),
            @ApiResponse(responseCode = "400", description = "已是VIP用户"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "404", description = "钱包不存在")
    })
    public HttpResult<VirtualWallet> upgradeToVip() {
        VirtualWallet wallet = virtualWalletService.upgradeToVip();
        return HttpResult.ok(wallet);
    }

    @GetMapping("/vip-status")
    @Operation(
            summary = "查询VIP状态",
            description = "查询当前用户是否为VIP用户"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "查询成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "404", description = "钱包不存在")
    })
    public HttpResult<Boolean> getVipStatus() {
        boolean isVip = virtualWalletService.isVipUser();
        return HttpResult.ok(isVip);
    }

    @PostMapping("/admin/migrate-wallets")
    @Operation(
            summary = "为现有用户创建钱包（管理员）",
            description = "为系统中所有还没有钱包的用户创建钱包，仅限管理员使用"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "迁移完成"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "权限不足，需要管理员权限")
    })
    @PreAuthorize("hasAuthority('ADMIN')")
    public HttpResult<String> migrateWalletsForExistingUsers() {
        long usersWithoutWallet = walletMigrationService.countUsersWithoutWallet();
        if (usersWithoutWallet == 0) {
            return HttpResult.ok("所有用户都已经拥有钱包，无需迁移");
        }

        int createdCount = walletMigrationService.createWalletsForExistingUsers();
        return HttpResult.ok(String.format("钱包迁移完成：成功为 %d 个用户创建了钱包", createdCount));
    }

    @GetMapping("/admin/users-without-wallet")
    @Operation(
            summary = "统计没有钱包的用户数量（管理员）",
            description = "获取系统中还没有钱包的用户数量，仅限管理员使用"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "查询成功"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "权限不足，需要管理员权限")
    })
    @PreAuthorize("hasAuthority('ADMIN')")
    public HttpResult<Long> countUsersWithoutWallet() {
        long count = walletMigrationService.countUsersWithoutWallet();
        return HttpResult.ok(count);
    }
}